import * as zrender from 'zrender';
import { setCurrentGroup } from './state';
import { getShiftTypeStroke } from './shift-type-stroke';
import { unitWidth } from '../../config';
import { useScheduleStore } from '../../../stores/schedule';

// 用于生成唯一ID的计数器
let shiftIdCounter = 0;

/**
 * 生成唯一的排班条ID
 * @param baseId 基础ID
 * @param suffix 后缀
 * @returns 唯一ID
 */
function generateUniqueShiftId(baseId: string, suffix: string): string {
  shiftIdCounter++;
  return `${baseId}_${suffix}_${shiftIdCounter}`;
}

/**
 * 设置排班条事件
 * @param group 排班条组
 * @param rect 排班矩形
 * @param shift 排班对象
 * @param personIndex 人员索引
 * @param shiftIndex 排班索引
 * @param chartState 图表状态对象
 * @param schedules 人员排班数据
 * @param redrawChart 重绘图表函数
 * @param currentGroup 当前操作组
 * @param zr ZRender实例
 */
export function setupScheduleEvents(
  group: any,
  rect: any,
  shift: Shift,
  personIndex: number,
  shiftIndex: number,
  chartState: ChartState,
  schedules: PersonSchedule[],
  redrawChart: RedrawChartFunction,
) {
  let isDragging = false;

  // 鼠标悬停事件
  group.on('mouseover', () => {
    if (isDragging || (group as any).resizing) {
      return;
    }
    rect.attr('style', {
      fill: zrender.color.lift(shift.fillColor, 0.3),
      stroke: getShiftTypeStroke(shift.type),
      lineWidth: 2,
    });
  });
  group.on('mouseout', () => {
    if (isDragging || (group as any).resizing) {
      return;
    }
    rect.attr('style', {
      fill: shift.fillColor,
      stroke: getShiftTypeStroke(shift.type),
      lineWidth: 2,
    });
  });

  // 拖拽事件
  group.on('dragstart', (e: any) => {
    // 检查是否正在调整大小
    if ((group as any).resizing) {
      e.event.preventDefault();
      e.event.stopPropagation();
      return;
    }
    isDragging = true;
    setCurrentGroup(group);
  });

  // 在拖拽结束时更新store
  group.on('dragend', (e: any) => {
    // 检查是否正在调整大小
    if ((group as any).resizing) {
      e.event.preventDefault();
      e.event.stopPropagation();
      return;
    }
    isDragging = false;

    // 计算新的时间位置
    const newX = group.x;
    const newStartTime = Math.round((newX - chartState.chartStartX) / unitWidth);

    // 更新store中的数据
    const scheduleStore = useScheduleStore();
    scheduleStore.updateShift(shift.personId, shift.id, { start: newStartTime });

    // 处理排班条重排（碰撞检测和自动让位）
    handleScheduleCollision(schedules, personIndex, shiftIndex, newStartTime);

    // 清除当前操作组
    setCurrentGroup(null);

    // 重绘图表
    redrawChart(true);
  });

  // 点击事件（可用于显示详情或编辑）
  group.on('click', () => {
    // TODO 显示排班条详情
    // if ((group as any).resizing) {
    //   return;
    // }
  });
}

/**
 * 处理排班条碰撞检测和自动重排
 * @param schedules 人员排班数据
 * @param personIndex 当前拖拽的人员索引
 * @param shiftIndex 当前拖拽的排班索引
 * @param newStartTIme 新的开始时间
 */
function handleScheduleCollision(
  schedules: PersonSchedule[],
  personIndex: number,
  shiftIndex: number,
  newStartTIme: number,
) {
  const currentShift = schedules[personIndex].shifts[shiftIndex];
  const currentDuration = currentShift.duration;
  const currentEnd = newStartTIme + currentDuration;

  // 更新当前排班条的位置
  currentShift.start = newStartTIme;

  // 检测与同一人员其他排班条的冲突
  const personShifts = schedules[personIndex].shifts;
  const conflictingShifts: Array<{ shift: Shift; index: number }> = [];

  for (let i = 0; i < personShifts.length; i++) {
    if (i === shiftIndex) {
      // 跳过当前排班条
      continue;
    }

    const otherShift = personShifts[i];
    const otherEnd = otherShift.start + otherShift.duration;

    // 检查是否重叠
    if (!(currentEnd <= otherShift.start || newStartTIme >= otherEnd)) {
      conflictingShifts.push({ shift: otherShift, index: i });
    }
  }

  // 处理冲突的排班条 - 计算被占据的区域并截取
  // 按索引倒序处理，避免索引变化影响后续处理
  conflictingShifts
    .sort((a, b) => b.index - a.index)
    .forEach(({ shift: conflictShift, index: conflictIndex }) => {
      handleOccupiedArea(schedules[personIndex], conflictShift, conflictIndex, currentShift);
    });
}

/**
 * 处理被占据的区域 - 计算重叠区域并截取排班条
 * @param personSchedule 人员排班数据
 * @param conflictShift 被占据的排班条
 * @param conflictIndex 被占据排班条的索引
 * @param currentShift 当前拖拽的排班条
 */
function handleOccupiedArea(
  personSchedule: PersonSchedule,
  conflictShift: Shift,
  conflictIndex: number,
  currentShift: Shift,
) {
  // 计算重叠区域
  const conflictStart = conflictShift.start;
  const conflictEnd = conflictStart + conflictShift.duration;
  const currentStart = currentShift.start;
  const currentEnd = currentStart + currentShift.duration;

  // 计算重叠区域
  const overlapStart = Math.max(conflictStart, currentStart);
  const overlapEnd = Math.min(conflictEnd, currentEnd);
  const overlapDuration = Math.max(0, overlapEnd - overlapStart);

  // 如果重叠时长等于被占据排班的时长，说明完全被占据
  if (overlapDuration >= conflictShift.duration) {
    console.log(`🗑️ 排班条 ${conflictShift.name} 完全被占据，删除`);
    personSchedule.shifts.splice(conflictIndex, 1);
    return;
  }

  // 计算截取后的排班条
  const remainingShifts: Shift[] = [];

  // 情况1: 重叠在排班条的前面部分
  if (overlapStart === conflictStart) {
    // 保留后半部分
    const remainingStart = overlapEnd;
    const remainingDuration = conflictEnd - remainingStart;

    if (remainingDuration > 0) {
      const remainingShift: Shift = {
        ...conflictShift,
        id: generateUniqueShiftId(conflictShift.id, 'part2'),
        start: remainingStart,
        duration: remainingDuration,
      };
      remainingShifts.push(remainingShift);
    }
  } else if (overlapEnd === conflictEnd) {
    // 情况2: 重叠在排班条的后面部分
    // 保留前半部分
    const remainingDuration = overlapStart - conflictStart;

    if (remainingDuration > 0) {
      const remainingShift: Shift = {
        ...conflictShift,
        id: generateUniqueShiftId(conflictShift.id, 'part1'),
        start: conflictStart,
        duration: remainingDuration,
      };
      remainingShifts.push(remainingShift);
    }
  } else {
    // 情况3: 重叠在排班条的中间部分
    // 保留前半部分
    const firstPartDuration = overlapStart - conflictStart;
    if (firstPartDuration > 0) {
      const firstPartShift: Shift = {
        ...conflictShift,
        id: generateUniqueShiftId(conflictShift.id, 'part1'),
        start: conflictStart,
        duration: firstPartDuration,
      };
      remainingShifts.push(firstPartShift);
    }

    // 保留后半部分
    const secondPartStart = overlapEnd;
    const secondPartDuration = conflictEnd - secondPartStart;
    if (secondPartDuration > 0) {
      const secondPartShift: Shift = {
        ...conflictShift,
        id: generateUniqueShiftId(conflictShift.id, 'part2'),
        start: secondPartStart,
        duration: secondPartDuration,
      };
      remainingShifts.push(secondPartShift);
    }
  }

  // 替换原排班条
  if (remainingShifts.length > 0) {
    // 删除原排班条
    personSchedule.shifts.splice(conflictIndex, 1);
    // 插入截取后的排班条
    personSchedule.shifts.splice(conflictIndex, 0, ...remainingShifts);
  } else {
    // 如果没有剩余部分，删除原排班条
    personSchedule.shifts.splice(conflictIndex, 1);
  }
}
